use diesel::{sqlite::Sqlite, Insertable, QueryResult, Queryable, Selectable};
use serde::{Deserialize, Serialize};
use crate::db::DB_POOL;
use diesel::prelude::*;
use crate::schema::gitlab_info::BoxedQuery;

#[derive(Debug, Clone, Serialize, Deserialize, Queryable, Selectable, Insertable, AsChangeset)]
#[diesel(table_name = crate::schema::gitlab_info)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct GitlabInfo {
    pub id: Option<i32>,
    pub host: Option<String>,
    pub token: Option<String>,
    pub user_id: Option<String>,
    pub user_name: Option<String>,
    pub user_email: Option<String>,
    pub https: Option<bool>,
}





//// 检查
pub async fn check(new_gitlab_info: &GitlabInfo) -> QueryResult<GitlabInfo> {
  let mut conn = DB_POOL.get().await.get().unwrap();

  let param = new_gitlab_info.clone();

  use crate::schema::gitlab_info::dsl::*;

  let mut query = gitlab_info.into_boxed();

  if let Some(_host) = param.host {
    query = query.filter(host.eq(_host));
  }
  if let Some(_token) = param.token {
    query = query.filter(token.eq(_token));
  }
  // println!("{}", diesel::debug_query::<Sqlite, _>(&query));
  query
    .select(GitlabInfo::as_select())
    .first(&mut conn)
}

//// 构建参数
pub fn build_query(new_gitlab_info: &GitlabInfo) -> BoxedQuery<'static, Sqlite> {
  use crate::schema::gitlab_info::dsl::*;
  let mut query = gitlab_info.into_boxed();
  let param = new_gitlab_info.clone();
  if let Some(_host) = param.host {
    query = query.filter(host.eq(_host));
  }
  if let Some(_token) = param.token {
    query = query.filter(token.eq(_token));
  }
  if let Some(_https) = param.https {
    query = query.filter(https.eq(_https));
  }
  query
}

//// 插入数据
pub async fn insert(new_gitlab_info: &GitlabInfo) -> QueryResult<GitlabInfo> {
  let mut conn = DB_POOL.get().await.get().unwrap();
  use crate::schema::gitlab_info;
  diesel::insert_into(gitlab_info::table)
    .values(new_gitlab_info)
    .returning(GitlabInfo::as_returning())
    .get_result(&mut conn)
}

//// 更新数据
pub async fn update_by_id(rid: i32, set_gitlab_info: &GitlabInfo) -> QueryResult<GitlabInfo> {
  let mut conn = DB_POOL.get().await.get().unwrap();
  use crate::schema::gitlab_info::dsl::*;

  let filter = gitlab_info.filter(id.eq(rid));

  diesel::update(filter)
    .set(set_gitlab_info)
    .returning(GitlabInfo::as_returning())
    .get_result(&mut conn)
}

//// 保存数据
pub async fn save(new_gitlab_info: &GitlabInfo) -> QueryResult<GitlabInfo> {
  if new_gitlab_info.id.is_none() {
    insert(new_gitlab_info).await
  } else {
    update_by_id(new_gitlab_info.id.unwrap(), new_gitlab_info).await
  }
}

pub async fn delete_by_id(rid: i32) -> QueryResult<usize> {
  let mut conn = DB_POOL.get().await.get().unwrap();
  use crate::schema::gitlab_info::dsl::*;
  let filter = gitlab_info.filter(id.eq(rid));
  diesel::delete(filter).execute(&mut conn)
}

//// 查询列表
pub async fn list(query: BoxedQuery<'static, Sqlite>) -> QueryResult<Vec<GitlabInfo>> {
  let mut conn = DB_POOL.get().await.get().unwrap();
  query
    .select(GitlabInfo::as_select())
    .load(&mut conn)
}

//// 查询单条
pub async fn one(query: BoxedQuery<'static, Sqlite>) -> QueryResult<GitlabInfo> {
  let mut conn = DB_POOL.get().await.get().unwrap();
  query
    .select(GitlabInfo::as_select())
    .first(&mut conn)
}

//// 查询总数
pub async fn count(query: BoxedQuery<'static, Sqlite>) -> QueryResult<i64> {
  let mut conn = DB_POOL.get().await.get().unwrap();
  query.count().get_result::<i64>(&mut conn)
}
